﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using DevExpress.XtraGrid;
using Fcdbas.WinUI.Common;
using Fcdbas.WinUI.Forms;
using Fcdbas.Core.Xml;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Columns;
using Fcdbas.Platform.Properties;
using Fcdbas.Core;

namespace Fcdbas.WinUI.Controls
{
    
    public enum RowFlags
    {
        None = 0,
        Edit = 1,
        New = 2,
        Removed = 3,
        Normal = 4
    }
    [Description("表示 Fcdbase 网格控件")]
    [ToolboxBitmap(typeof(GridControl))]
    [ToolboxItemFilter("System.Windows.Forms")]
    public class cGridControl : GridControl, IOwningDataSourceBinding, IEnumMethod,IValidate
    {
        private GridView gridView1;
    
        public GridSetting gridSetting { get; set; }
        /// <summary>
        /// 是否初始化右键菜单
        /// </summary>
        public bool IsInitPopupMenu
        { get; set; }
        public cGridControl()
        {
            IsInitPopupMenu = false;
            IsTranslate = true;
            IsClearLayout = false;
           // GridView gridView = this.MainView as GridView;
            //gridView.OptionsView.ShowGroupPanel = false;
        }
        public bool IsClearLayout
        {
            get;
            set;
        }
        private cLabel bindLabel;
        public cLabel BindLabel
        {
            get
            {
                return this.bindLabel;
            }
            set
            {
                this.bindLabel = value;
            }
        }
        private int FindColumn(string name)
        {
            for (int i = 0; i < gridSetting.ColumnSettings.Count; i++)
            {
                if (gridSetting.ColumnSettings[i].Name == name)
                    return i;
            }
            return -1;
        }

        /// <summary>
        /// 是否自动翻译
        /// </summary>
        [Browsable(true), Description("是否自动翻译"), DefaultValue(true)]
        public bool IsTranslate { get; set; }

        private GridColumn FindColumnByName(string name)
        {
            GridView gridView = this.MainView as GridView;
            if (gridView == null)
                return null;
            foreach (GridColumn col in gridView.Columns)
            {
                if (col.Name == name)
                    return col;
            }
            return null;
        }
        private DataItem GetBindingItem()
        {
            DataSourceBinding ownerDataSourceBinding = GetOwningDataSourceBinding();
            if (ownerDataSourceBinding == null)
                return null;

            DataItem bindingItem = ownerDataSourceBinding.GetDataItemByColumnName(this.DataBindings["Text"].BindingMemberInfo.BindingMember);
            if (bindingItem != null)
                return bindingItem;

            return null;
        }

        private DataSourceBinding GetOwningDataSourceBinding()
        {
            if (this.DataSource == null)
                return null;

            return this.DataSource as DataSourceBinding;
        }
        #region IOwningDataSourceBinding 成员
        private Binding _oldBinding;
        public Binding OldBinding
        {
            get
            {
                return _oldBinding;
            }
            set
            {
                _oldBinding = value;
            }
        }
        [Browsable(false)]
        public DataSourceBinding OwningDataSourceBinding
        {
            get { return GetOwningDataSourceBinding(); }
        }

        [Browsable(false)]
        DataSourceBinding IOwningDataSourceBinding.OwningDataSourceBinding
        {
            get { return OwningDataSourceBinding; }
        }

        [Browsable(false)]
        DataItem IOwningDataSourceBinding.BindingItem
        {
            get
            {
                return GetBindingItem();
            }
        }

        #endregion

        protected override void OnEnter(EventArgs e)
        {

            BaseForm parentForm = this.FindForm() as BaseForm;
            if (parentForm != null)
                parentForm.FireOnEnterEvent(this);

            base.OnEnter(e);
        }
        public void SetEnums()
        {
            DataSourceBinding dsb = GetOwningDataSourceBinding();
            if (dsb == null)
                return;
            if (dsb.Columns == null)
                return;

            foreach (GridColumn viewColumn in ((GridView)this.MainView).Columns)
            {
                if (dsb.Columns != null)
                {
                    DataItem dataItem = dsb.Columns.Find(p => p.ColumnName == viewColumn.FieldName);
                    if (dataItem != null)
                    {
                        if (!string.IsNullOrEmpty(dataItem.EnumMethod))
                        {
                            if (viewColumn.ColumnEdit is DevExpress.XtraEditors.Repository.RepositoryItemComboBox)
                            {
                                DevExpress.XtraEditors.Repository.RepositoryItemComboBox pTypeCombBox = viewColumn.ColumnEdit as DevExpress.XtraEditors.Repository.RepositoryItemComboBox;
                                if (pTypeCombBox != null)
                                {
                                    List<string> list = dsb.GetEnums(dataItem.EnumMethod);
                                    foreach (string item in list)
                                        pTypeCombBox.Items.Add(item);
                                }
                            }
                            if (viewColumn.ColumnEdit is DevExpress.XtraEditors.Repository.RepositoryItemImageComboBox)
                            {
                                DevExpress.XtraEditors.Repository.RepositoryItemImageComboBox imgComboBox = viewColumn.ColumnEdit as DevExpress.XtraEditors.Repository.RepositoryItemImageComboBox;
                                List<string> list = dsb.GetEnums(dataItem.EnumMethod);
                                int idx = 0;
                                foreach (string item in list)
                                {
                                    
                                    DevExpress.XtraEditors.Controls.ImageComboBoxItem imgitem = new DevExpress.XtraEditors.Controls.ImageComboBoxItem(item);
                                    imgComboBox.Items.Add(imgitem);
                                    if(imgComboBox.SmallImages != null)
                                    {
                                        ImageList ilist = imgComboBox.SmallImages as ImageList;
                                        if (ilist != null && ilist.Images.Count > 0)
                                        {
                                            imgitem.ImageIndex = idx;
                                            if (idx < ilist.Images.Count)
                                                idx++;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        private SalBoolean SalAnyRow(IEntity en, RowFlags nFlagOn, RowFlags nFlagOff)
        {
            SalBoolean res = 0;
            if (nFlagOn > 0)
            {
                switch (nFlagOn)
                {
                    case RowFlags.Edit:
                        if (en.Status == RecordStatus.Edit)
                            return 1;
                        break;
                    case RowFlags.New:
                        if (en.Status == RecordStatus.New)
                            return 1;
                        break;
                    case RowFlags.Removed:
                        if (en.Status == RecordStatus.Delete)
                            return 1;
                        break;
                }
            }
            else if (nFlagOn == RowFlags.None)
            {
                switch (nFlagOff)
                {
                    case RowFlags.Edit:
                        if (en.Status != RecordStatus.Edit)
                            return 1;
                        break;
                    case RowFlags.New:
                        if (en.Status != RecordStatus.New)
                            return 1;
                        break;
                    case RowFlags.Removed:
                        if (en.Status != RecordStatus.Delete)
                            return 1;
                        break;

                }

            }
            return 0;
        }
        /// <summary>
        /// boolean = SalFindNextRow(nRow, nFlagOn, nFlagOff) 查询满足状态要求的记录行
        //其中, nRow是返回的行号(GridView, INOUT类型, 查询nRow的下一行, 如果是 -1 就说明从第一行开始往下)
        /// </summary>
        /// <param name="nRow"></param>
        /// <param name="nFlagOn"></param>
        /// <param name="nFlagOff"></param>
        /// <returns></returns>
        public SalBoolean SalFindNextRow(ref SalNumber nRow, RowFlags nFlagOn, RowFlags nFlagOff)
        {

            if (this.DataSource == null)
            {
                nRow = -1;
                return 0;
            }
            DataSourceBinding dsb = this.DataSource as DataSourceBinding;
            if (dsb == null || dsb.Count == 0 || nRow > dsb.Count)
            {
                nRow = -1;
                return 0;
            }
            if (nRow == -1)
                nRow = 0;
            else
                nRow++;
            GridView view = this.MainView as GridView;
            while (nRow < dsb.Count)
            {
                IEntity en = view.GetRow(nRow) as IEntity;
                if (en != null)
                {
                    if (SalAnyRow(en, nFlagOn, nFlagOff))
                        return 1;
                }
                nRow++;
            }
            nRow = -1;
            return 0;
        }
        
        /// <summary>
        /// boolean = SalFindPrevRow(nRow, nFlagOn, nFlagOff) 查询满足状态要求的记录行
        ///其中, nRow是返回的行号(GridView, INOUT类型, 查询nRow的下一行, 如果是 -1 就说明从最后一行开始往上查询)
        /// </summary>
        /// <param name="nRow"></param>
        /// <param name="nFlagOn"></param>
        /// <param name="nFlagOff"></param>
        /// <returns></returns>
        public SalBoolean SalFindPrevRow(ref SalNumber nRow, RowFlags nFlagOn, RowFlags nFlagOff)
        {
            if (this.DataSource == null)
            {
                nRow = -1;
                return 0;
            }
            DataSourceBinding dsb = this.DataSource as DataSourceBinding;
            if (dsb == null || dsb.Count == 0 || nRow > dsb.Count)
            {
                nRow = -1;
                return 0;
            }
            if (nRow == -1)
                nRow = dsb.Count - 1;
            else
                nRow--;
            GridView view = this.MainView as GridView;
            while (nRow >=0)
            {
                IEntity en = view.GetRow(nRow) as IEntity;
                if (en != null)
                {
                    if (SalAnyRow(en, nFlagOn, nFlagOff))
                        return 1;
                }
                nRow--;
            }
            nRow = -1;
            return 0;
        }
        //
       /// <summary>
       /// boolean = SalSetRowFlags( nRow, nFlags, bSet): 设置状态
       ///其中, nFlags包括(New, Edited, MarkDeleted), bSet如果为True,则设置状态, 如果为False则是取消已经存在的状态
       /// </summary>
       /// <param name="nRow"></param>
       /// <param name="nFlags"></param>
       /// <param name="bSet"></param>
       /// <returns></returns>
        public SalBoolean SalSetRowFlags(SalNumber nRow, RowFlags nFlags, SalBoolean bSet)
        {
            if (this.DataSource == null)
            {
                nRow = -1;
                return 0;
            }
            DataSourceBinding dsb = this.DataSource as DataSourceBinding;
            if(nRow < 0 || nRow >= dsb.Count )
                return 0;
            GridView view = this.MainView as GridView;
            IEntity en = view.GetRow(nRow) as IEntity;
            if(en == null)
                return 0;
            switch(nFlags)
            {
                case RowFlags.Edit:
                    if(bSet)
                        en.Status = RecordStatus.Edit;
                    else
                        en.Status = RecordStatus.Normal;
                    break;
                case RowFlags.New:
                    if(bSet)
                        en.Status = RecordStatus.New;
                    else
                        en.Status = RecordStatus.Normal;

                    break;
                case RowFlags.Removed:
                    if(bSet)
                        en.Status = RecordStatus.Delete;
                    else
                        en.Status = RecordStatus.Normal ;
                    break;
                default:
                    return 0;
            }
            return 1;
        }
//
        /// <summary>
        /// boolean = SalQueryRowFlag( nRow, nFlags): 查询状态
        /// 其中, nRow为需要判断的行, nFlag返回对应的状态(Out类型)
        /// </summary>
        /// <param name="nRow"></param>
        /// <param name="nFlags"></param>
        /// <returns></returns>
        public SalBoolean SalQueryRowFlag(SalNumber nRow,RowFlags nFlags)
        {
            if (this.DataSource == null)
            {
                nRow = -1;
                return 0;
            }
            DataSourceBinding dsb = this.DataSource as DataSourceBinding;
            if(nRow < 0 || nRow >= dsb.Count )
                return 0;
            GridView view = this.MainView as GridView;
            IEntity en = view.GetRow(nRow) as IEntity;
            if(en == null)
                return 0;
            switch(nFlags)
            {
                case RowFlags.Edit:
                    if (en.Status == RecordStatus.Edit)
                        return 1;
                    
                    break;
                case RowFlags.New :
                    if (en.Status == RecordStatus.New)
                        return 1;
                    break;
                case RowFlags.Removed:
                    if (en.Status == RecordStatus.Delete)
                        return 1;
                    break;
                default:
                    return 0;
            }
            return 0;
        }
        /// <summary>
        /// 获取选择的实例对象列表
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public List<T> GetSelectEntityList<T>()  where T:class,IEntity 
        {
            List<T> list = new List<T>();
            GridView gview = this.MainView as GridView ;
            int[] selects = gview.GetSelectedRows();
            foreach (int idx in selects)
            {
                T t = gview.GetRow(idx) as T;
                list.Add(t);
            }
            return list;
        }
        public bool Validate()
        {
            DataSourceBinding ownerDataSourceBinding = GetOwningDataSourceBinding();
            if (ownerDataSourceBinding == null || ownerDataSourceBinding.Columns == null)
                return true;
            bool valid = true;
            IEntityList list = ownerDataSourceBinding.DataSource as IEntityList;
            if (list == null)
                return true;
            foreach (IEntity en in list)
            {
                if (en.Status == RecordStatus.Normal || en.Status == RecordStatus.Delete)
                    continue;
                foreach (DataItem dataItem in ownerDataSourceBinding.Columns)
                {
                    object v = en[dataItem.ColumnName];
                   
                    if (dataItem != null &&
                           dataItem.Required &&
                           (v == null || string.IsNullOrEmpty(v.ToString())))
                    {

                        WinUI.Forms.BaseForm form = this.FindForm() as WinUI.Forms.BaseForm;
                        if (form != null)
                            form.ShowMessage("字段[%%1]不能为空！", dataItem.Caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                        return false;
                    }
                    if(v != null)
                        valid = ownerDataSourceBinding.Validate(dataItem.ColumnName, v.ToString());
                    if (!valid)
                        break;
                }
            }
            return valid;
        }
        private bool _isLoadLayout = false;
        [Category("Fcdbase 属性")]
        [Description("是否自动加载Grid的布局,false加载"), DefaultValue(false)]
        public bool IsLoadLayout
        {
            get
            {
                return _isLoadLayout;
            }
            set
            {
                _isLoadLayout = value;
            }
        }
        public override object DataSource
        {
            get
            {
                return base.DataSource;
            }
            set
            {

                base.DataSource = value;
                Control ctrl = this.Parent;
                if (ctrl == null)
                    return;
                while (ctrl.Parent != null)
                {
                    ctrl = ctrl.Parent;
                }
                Form frm = ctrl as BaseForm;
                //WinTranslate tra = null;
                //if (frm != null)
                //    tra = ((BaseForm)frm).translate;
                //if (frm == null)
                //{
                //    frm = ctrl as MainForm;
                //    if(frm != null)
                //        tra = ((MainForm)frm).translate;
                //}
                if (frm != null && !IsLoadLayout)
                {
                    //if (IsTranslate)
                    //{
                    //    if (tra != null && frm is BaseForm)
                    //        tra.TranslateGridControl(((BaseForm)frm).FormName, this);
                    //    if (tra != null && frm is MainForm)
                    //        tra.TranslateGridControl(((MainForm)frm).FormName, this);
                    //}
                    string file = Application.StartupPath + "\\Layouts\\";
                    if (!System.IO.Directory.Exists(file))
                        System.IO.Directory.CreateDirectory(file);
                    file += System.Diagnostics.Process.GetCurrentProcess().ProcessName + "-" + frm.Name + "-" + this.Name + "UserDefine.xml";
                    gridSetting = file.ToXmlFileEntity<GridSetting>();
                    GridView gridView = this.MainView as GridView;
                    if (gridSetting != null && gridView != null)
                    {
                        //加载列的设置
                        for (int i = 0; i < gridView.Columns.Count; i++)
                        {
                            GridColumn col = gridView.Columns[i];
                            int idx = FindColumn(col.FieldName);
                            if (idx > 0)
                            {
                                col.Caption = gridSetting.ColumnSettings[idx].Caption;
                                col.AppearanceCell.TextOptions.HAlignment = (DevExpress.Utils.HorzAlignment)gridSetting.ColumnSettings[idx].Alignment.Value;
                                col.Visible = gridSetting.ColumnSettings[idx].Visible;
                                col.DisplayFormat.FormatType = gridSetting.ColumnSettings[idx].FormatType;
                                col.DisplayFormat.FormatString = gridSetting.ColumnSettings[idx].Format;
                            }
                        }
                        //加载高亮设置
                        foreach (GridFormatCondition gfc in gridSetting.FormatConditions)
                        {
                            StyleFormatCondition item = new StyleFormatCondition();
                            GridColumn col = FindColumnByName(gfc.ColumnName);
                            if (col == null)
                                continue;
                            item.Column = col;
                            item.Value1 = gfc.Value1;
                            item.Value2 = gfc.Value2;
                            item.ApplyToRow = gfc.ApplyToRow;
                            item.ColumnName = gfc.ColumnName;
                            item.Condition = gfc.FormatCondition;
                            item.Appearance.ForeColor = Color.FromArgb(gfc.ForeColor);
                            item.Appearance.BackColor = Color.FromArgb(gfc.BackColor);
                            item.Appearance.BackColor2 = Color.FromArgb(gfc.BackColor2);
                            item.Appearance.BorderColor = Color.FromArgb(gfc.BorderColor);
                            item.Appearance.Options.UseForeColor = gfc.UseForeColol;
                            item.Appearance.Options.UseBackColor = gfc.UseBackColor;
                            item.Appearance.Options.UseBorderColor = gfc.UseBordColor;
                            gridView.FormatConditions.Add(item);
                        }
                        gridView.BestFitColumns();
                    }
                }
            }
        }

        private void InitializeComponent()
        {
            this.gridView1 = new DevExpress.XtraGrid.Views.Grid.GridView();
            ((System.ComponentModel.ISupportInitialize)(this.gridView1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
            this.SuspendLayout();
            // 
            // gridView1
            // 
            this.gridView1.GridControl = this;
            this.gridView1.Name = "gridView1";
            // 
            // cGridControl
            // 
            this.MainView = this.gridView1;
            this.ViewCollection.AddRange(new DevExpress.XtraGrid.Views.Base.BaseView[] {
            this.gridView1});
            ((System.ComponentModel.ISupportInitialize)(this.gridView1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this)).EndInit();
            this.ResumeLayout(false);

        }
    }
}
